package Messaging;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
 * @author Roch San Buenaventura
 */

public class EventCallback 
{

	private Object Object_;
	private Method Method_;

	public EventCallback(Object object, Method method) 
	{
		Object_ = object;
		Method_ = method;
	}

	public void notifyObserver(Object updatedObject, String event, boolean terminal) 
	{
		try 
		{
			if (Method_.getParameterTypes().length == 1)
				Method_.invoke(Object_, updatedObject);
			
			else if (Method_.getParameterTypes().length == 0)
				Method_.invoke(Object_);
			
			else if (Method_.getParameterTypes().length == 2)
				Method_.invoke(Object_, updatedObject, event);
			
			else if (Method_.getParameterTypes().length == 3)
				Method_.invoke(Object_, updatedObject, event);
			
			else if (Method_.getParameterTypes().length == 4)
				Method_.invoke(Object_, updatedObject, event);
			
			else if (Method_.getParameterTypes().length == 5)
				Method_.invoke(Object_, updatedObject, event);
			
			else if (Method_.getParameterTypes().length == 6)
				Method_.invoke(Object_, updatedObject, event);
			
			else if (Method_.getParameterTypes().length == 7)
				Method_.invoke(Object_, updatedObject, event, terminal);
			
			else
				System.err.println(this + " does not contain 0 or 1 parameter");
		}
		
		catch (IllegalAccessException e) 
		{
			String error = "An IllegalAccessException has occured while trying to" + "notify "	+ Object_.getClass() + " with method " + Method_.getName();
			System.err.println(error);
		}
		
		catch (InvocationTargetException e) 
		{
			String error = "An InvocationTargetException has occured while trying to" + "notify " + Object_.getClass() + " with method " + Method_.getName() + "\n I suggest going to target method, catching exception and printing stack trace";
			System.err.println(error);
			e.printStackTrace();
		} 
		catch (IllegalArgumentException e) 
		{
			String error = "An IllegalArgumentException has occured while trying to" + "notify " + Object_.getClass() + " with method " + Method_.getName() + "\n Remember all methods that are updated are expected to have either" + " an object parameter, an object and String parameter, or no parameters at all";
			System.err.println(error);
		}
	}

	public boolean equals(Object obj) 
	{
		if (this == obj)
			return true;
		
		if (!(obj instanceof EventCallback))
			return false;
		
		EventCallback callback = (EventCallback) obj;

		return Object_.equals(callback.Object_)
				&& Method_.equals(callback.Method_);
	}

	public Object getObject() 
	{
		return Object_;
	}

	public Method getMethod() 
	{
		return Method_;
	}

	public String toString() 
	{
		return "Class: " + Object_.getClass() + ", Method: " + Method_.getName();
	}
}
